/**
 * 
 */
package com.yuyi.lwq.controller;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.yuyi.full.handler.exception.ResultBO;
import org.yuyi.full.handler.exception.ResultTool;

import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPayConstants.SignType;
import com.github.wxpay.sdk.WXPayUtil;
import com.yuyi.lwq.wxpay.PayConfig;
import com.yuyi.lwq.wxpay.WXPayClient;

/**
 *
 * @author 李文庆
 * 2018年7月19日 下午8:00:27
 */
@RestController
public class PayController {
	
	private static final Logger log = LoggerFactory.getLogger(PayController.class);
	
	@Autowired
	private RestTemplate restTemplate;
	
	/**
	 * 小程序调用此API获取openid
	 * @param code
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/openid")
	public ResultBO<Object> getOpenId(@RequestParam String code)throws Exception{
		
		JSONObject response = restTemplate.getForObject(
				"https://api.weixin.qq.com/sns/jscode2session?appid="+PayConfig.JS_APP_ID
				+"&secret="+PayConfig.JS_APP_SECRET+"&js_code="+code+"&grant_type=authorization_code",
				JSONObject.class);
		if (response.containsKey("openid")) {
			String openid = response.getString("openid");
			String session_key = response.getString("session_key");
			JSONObject json = new JSONObject();
			json.put("openid",openid);
			json.put("session_key", session_key);
			return ResultTool.success(json);
		}
		return ResultTool.success();
		
	}
	
	/**统一下单
	 * @param from
	 * @param openid
	 * @param out_trade_no
	 * @param body
	 * @param total_fee
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/pay")
	public ResultBO<Object> pay(@RequestParam Integer from,
			 					@RequestParam(defaultValue="") String openid,
								@RequestParam String out_trade_no,
								@RequestParam String body,
								@RequestParam String total_fee) throws Exception{
		
		//对参数的限制逻辑
		
		Map<String, String> order = WXPayClient.getOrder(from, openid, out_trade_no,body,total_fee,"attach");
		log.info("{}",order);
		String returnCode = order.get("return_code");
		String resultCode = order.get("result_code");
		String errCodeDes = order.get("err_code_des");
		
		//请求微信后台失败
		if (Objects.equals(returnCode,"FAIL")) {
			log.info(errCodeDes);
			//失败后的处理。
		}
		if (Objects.equals(resultCode, "FAIL")) {
			//失败后的处理，
		}
		//请求成功
		if (Objects.equals(resultCode,"SUCCESS")) {
			//根据不同的客户端构造不同的返回参数
			Map<String, String> param = getResponse(from, order);
			return ResultTool.success(param);
		}
		
		return ResultTool.success();
	}
	
	/**
	 * 针对不同的客户端构造不同的返会信息
	 * @param from
	 * @param order
	 * @return
	 * @throws Exception
	 */
	public static Map<String, String> getResponse(Integer from,Map<String,String> order) throws Exception{
		
		String js_app_id = PayConfig.JS_APP_ID;
		String app_id = PayConfig.APP_ID;
		String partnerid = PayConfig.MCH_ID;
		String nonce_str = order.get("nonce_str");
		String prepay_id = order.get("prepay_id");
		String timeStamp = String.valueOf(new Date().getTime());
		timeStamp = timeStamp.substring(0,timeStamp.length()-3);
		
		if (Objects.equals(from, 2)) {
			//app支付
			Map<String,String> param = new HashMap<String, String>();
			param.put("appid",app_id);
			param.put("partnerid", partnerid);
			param.put("prepayid", prepay_id);
			param.put("noncestr", nonce_str);
			param.put("timestamp", timeStamp);
			param.put("package", "Sign=WXPay");
			String sign = WXPayUtil.generateSignature(param, PayConfig.KEY, SignType.HMACSHA256);
			param.put("sign", sign);
			
			return param;
		}else if(Objects.equals(from, 1)){ 
			//扫码支付
			String content = order.get("code_url");
			Map<String,String> param = new HashMap<String, String>();
			param.put("codeUrl", content);
			return param;
		}else if(Objects.equals(from, 3)){
			//小程序支付
			Map<String,String> param = new HashMap<String, String>();
			param.put("appId", js_app_id);
			param.put("timeStamp",timeStamp);
			param.put("nonceStr",nonce_str);
			param.put("package", "prepay_id="+prepay_id);
			param.put("signType", "HMAC-SHA256");
			String sign = WXPayUtil.generateSignature(param, PayConfig.KEY,SignType.HMACSHA256);
			param.put("paySign", sign);
			
			return param;
		}
		return null;
	}
	
	/**
	 * 关闭订单
	 * @param out_trade_no
	 * @return
	 * @throws Exception
	 */
	@PostMapping("closeorder")
	public ResultBO<Object> closeOrder(@RequestParam String out_trade_no) throws Exception{
		
		Map<String, String> order = WXPayClient.closeOrder(out_trade_no);
		return ResultTool.success(order);
	}
	
	/**
	 * 订单支付状态查询
	 * @param out_trade_no
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/orderquery")
	public ResultBO<Object> orderQuery(@RequestParam String out_trade_no) throws Exception{
		
		Map<String, String> queryOrder = WXPayClient.queryOrder(out_trade_no);
		String returnCode = queryOrder.get("return_code");
		String resultCode = queryOrder.get("result_code");
		String errCodeDes = queryOrder.get("err_code_des");
		log.info("{}",queryOrder);
		/**退款请求失败！！*/
		if (Objects.equals(returnCode,"FAIL")) {
			log.info(errCodeDes);
		}
		if (Objects.equals(resultCode,"FAIL")) {
			log.info(errCodeDes);
		}
		//退款请求成功
		if (Objects.equals(queryOrder.get("result_code"),"SUCCESS")) {
			String state = queryOrder.get("trade_state");
			/**1、订单已关闭*/
			if (Objects.equals(state,"CLOSED")) {
				//
			}
			if (Objects.equals(state,"REFUND")) {
				//
			}
			if (Objects.equals(state,"NOTPAY")) {
				//
			}
			if (Objects.equals(state,"SUCCESS")) {
				
				//订单支付状态的修改
				//
			}
		}
		
		return ResultTool.success(queryOrder);
	}
	
	/**
	 * 退款
	 * @param out_trade_no
	 * @param refundNumber
	 * @param totalPrice
	 * @param refundPrice
	 * @return
	 * @throws Exception
	 */
	@PostMapping("refund")
	public ResultBO<Object> refund(@RequestParam String out_trade_no,
								   @RequestParam String refundNumber, 
								   @RequestParam String totalPrice,
								   @RequestParam String refundPrice) throws Exception{
		
		String out_refund_no = "";
		
		Map<String, String> refund = WXPayClient.refund(out_trade_no, refundNumber, totalPrice, refundPrice);
		String returnCode = refund.get("return_code");
		String resultCode = refund.get("result_code");
		String errCodeDes = refund.get("err_code_des");
		log.info("{}",refund);
		/**退款请求失败！！*/
		if (Objects.equals(returnCode,"FAIL")) {
			log.info(errCodeDes);
		}
		if (Objects.equals(resultCode,"FAIL")) {
			log.info(errCodeDes);
		}
		//退款请求成功
		if (Objects.equals(refund.get("result_code"),"SUCCESS")) {
			JSONObject json = new JSONObject();
			json.put("out_refund_no",out_refund_no);
			return ResultTool.success(json);
		}
		return ResultTool.success();
	}
	
	/**
	 * 退款查询
	 * @param out_trade_no
	 * @return
	 * @throws Exception
	 */
	@PostMapping("/refundquery")
	public ResultBO<Object> refundQuery(@RequestParam String out_trade_no) throws Exception{
		
		Map<String, String> refundQuery = WXPayClient.refundQuery(out_trade_no);
		String returnCode = refundQuery.get("return_code");
		String resultCode = refundQuery.get("result_code");
		String errCodeDes = refundQuery.get("err_code_des");
		log.info("{}",refundQuery);
		/**请求失败！！*/
		if (Objects.equals(returnCode,"FAIL")) {
			log.info(errCodeDes);
		}
		if (Objects.equals(resultCode,"FAIL")) {
			log.info(errCodeDes);
		}
		//退款请求成功
		if (Objects.equals(resultCode,"SUCCESS")) {
			
			String refund_status = refundQuery.get("refund_status_0");
			if (Objects.equals(refund_status,"SUCCESS") ) {
				String refund_id = refundQuery.get("refund_id_0");//退款单号
				String refund_channel = refundQuery.get("refund_channel_0");//退款渠道：ORIGINAL->原路退款
				String refund_recv_accout = refundQuery.get("refund_recv_accout_0");//退款入账账户，即钱退到哪里了。
				String refund_time = refundQuery.get("refund_success_time_0");//退款成功时间
				
				//退款状态的修改
				
				JSONObject json = new JSONObject();
				json.put("refund_status", refund_status);
				json.put("refund_id", refund_id);
				json.put("refund_channel", refund_channel);
				json.put("refund_recv_accout", refund_recv_accout);
				json.put("refund_time", refund_time);
					
				return ResultTool.success(json);
				
			}
			if (Objects.equals(refund_status,"REFUNDCLOSE") ) {
				
			}
			if (Objects.equals(refund_status,"PROCESSING") ) {
				
			}
			if (Objects.equals(refund_status,"CHANGE") ) {
				
			}
			
		}
		return ResultTool.success();
	}
	
	@PostMapping("/downloadbill")
	public ResultBO<Object> downloadBill(@RequestParam String bill_date) throws Exception{
		
		Map<String, String> down = WXPayClient.downloadBill(bill_date);
		System.out.println(down.get("data"));
		return ResultTool.success(down);
	}
	
}
